コンピュータサイエンスにおいて、三者比較は、全順序を持つ型に属する2つの値AとBを取り、数学的な三分法の法則に従って、 1回の演算でA < B、A = B、またはA > Bのいずれであるかを決定します
これは、関数strcmp( Cなど)、メソッドcompareTo( Javaなど)、または演算子( Perl、PHP、C++の宇宙船演算子など)として実装できます。 <=>
マシンレベルの計算
多くのプロセッサは、プリミティブ型に対してこのような演算[ a ]をサポートする命令セットを備えています。一部のマシンは、符号と絶対値に基づく符号付き整数、または1の補数表現(符号付き数値表現を参照)に基づいており、どちらも区別された正と負のゼロを許容します。これは、一貫した全順序が採用されている限り、三分法に違反しません。-0 = +0 または -0 < +0 のいずれかが有効です。ただし、一般的な浮動小数点型には三分法の例外があります。特別な値「NaN」(非数)があり、 x < NaN、x > NaN、x = NaN はすべて、すべての浮動小数点値x(NaN自体を含む) に対して偽となります
高水準言語
能力
C言語では、関数strcmpと関数はmemcmpそれぞれ文字列とメモリバッファの3者間比較を実行します。最初の引数が2番目の引数より辞書順で小さい場合は負の数を、引数が等しい場合はゼロを、それ以外の場合は正の数を返します。この「差の符号」を返すという規則は、標準的なソート関数によって任意の比較関数に拡張されています。ソート関数qsortは比較関数を引数として取り、ソート関数はそれに従う必要があります
Perl (数値比較のみ、cmp演算子は文字列の字句比較に使用)、PHP(バージョン7以降)、Ruby、Apache Groovyでは、「宇宙船演算子」は<=>、A < B、A = B、A > Bのいずれであるかに応じて、それぞれ-1、0、1の値を返します。Python 2.x cmp(3.xでは削除)、OCamlcompare、KotlinのcompareTo関数も同じものを計算します。Haskell標準ライブラリでは、クラス内のすべての型に対して3者間比較関数が定義されており、値が(より小さい)、(等しい)、(より大きい)である型を返します。 [ 2 ]compareOrdOrderingLTEQGT
データの順序= LT | EQ | GT多くのオブジェクト指向プログラミング言語には、オブジェクトと別の特定のオブジェクトとの間で3者間比較を実行する3者間比較関数 があります。たとえば、Javaでは、インターフェイスを実装するクラスには、負の整数、ゼロ、または正の整数を返すか、(一方または両方のオブジェクトが の場合)をスローする メソッドがあります。同様に、.NET Framework では、インターフェイスを実装するクラスには、そのような メソッドがあります。C ++では、3者間比較が可能なクラスは、、、、またはのインスタンスのパラメータにすることができます。 ComparablecompareToNullPointerExceptionnullIComparableCompareTostd::compare_three_waystd::strong_orderstd::weak_orderstd::partial_order
Javaバージョン1.5以降では、後述する算術オーバーフローMath.signumなどの計算上の問題なしに差がわかる場合、静的メソッドを使用して同じ計算を行うことができます。多くのコンピュータ言語では関数の定義が許可されているため、compare(A,B)を適切に設計することは可能ですが、問題は、その内部定義で何らかの3元構文を使用できるかどうか、あるいは繰り返しテストに頼らなければならないかどうかです。
3 方向比較演算子またはメソッドがまだ利用できない環境で 3 方向比較を実装する場合は、A = B と A < B、または A < B と A > B のように、2 つの比較を組み合わせるのが一般的です。 原理的には、コンパイラはこれらの 2 つの式を 1 つの比較とそれに続く複数の結果テストに置き換えることができると推測する可能性がありますが、この最適化に関する記述は、この主題に関するテキストには見つかりません。
場合によっては、AとBを減算し、その結果の符号を調べることで、3者間比較をシミュレートできます。これは、数値の符号を調べるための特別な命令を利用することで実現できます。ただし、そのためには、AとBの型に明確な差が必要です。固定幅の符号付き整数は減算時にオーバーフローする可能性があり、浮動小数点数は符号が定義されていないNaN値を持ちます。また、文字列には全体の順序に対応する差関数がありません。マシンレベルでは、オーバーフローは通常追跡され、減算後の順序を決定するために使用できますが、この情報は通常、高水準言語では利用できません。
プログラミング言語によって提供される3 方向条件の 1 つの例として、 Fortranの現在非推奨となっている 3 方向算術 IFステートメントは算術式の符号を考慮し、結果の符号に応じてジャンプする 3 つのラベルを提供します。
IF (式)負、ゼロ、正Cおよび関連言語の共通ライブラリ関数strcmp は、文字列の 3 方向辞書式比較です。ただし、これらの言語には他のデータ型の一般的な 3 方向比較がありません。
宇宙船演算子
数値の3元比較演算子、または「宇宙船演算子」は、Perl、Ruby、Apache Groovy、PHP、Eclipse Ceylon、C++<=>ではと表記され、宇宙船演算子と呼ばれます。[ 3 ]
C++では、C++20リビジョンで宇宙船演算子が追加されました。<=>この演算子は、2つの値が等しいか、小さいか、大きいか、順序付けられていないかをエンコードした値を返します。比較の厳密さに応じて異なる型を返すことができます。[ 4 ]
名前の由来は、ランドール・L・シュワルツがHP BASICのスタートレックゲームに登場する宇宙船を思い起こさせたことに由来する。[ 5 ]別のプログラマーは、スターウォーズシリーズに登場するダース・ベイダーのTIEファイターに似ていることからこの名前が付けられたと示唆している。[ 6 ]
PHPの例:
echo 1 <=> 1 ; // 0 echo 1 <=> 2 ; // -1 echo 2 <=> 1 ; // 1C++ の例:
1 <=> 1 ; // std::strong_ordering::equal と評価されます1 <=> 2 ; // std::strong_ordering::less と評価されます2 <=> 1 ; // std::strong_ordering::greater と評価されます複合データ型
3者間比較は、2者間比較とは異なり、非プリミティブデータ型の 辞書式比較を簡単に作成および構築できるという特性があります
以下は Perl での構成例です。
sub compare ($$) { my ( $a 、$b ) = @_ ; return $a -> { unit } cmp $b -> { unit } || $a -> { rank } <=> $b -> { rank } || $a -> { name } cmp $b -> { name }; }cmpPerlでは、 は文字列用であり、 は数値用であることに注意してください<=>。双方向同値演算子は簡潔さが欠ける傾向がありますが、必ずしも読みやすさが劣るわけではありません。上記の演算子は、演算子の短絡評価||と、Perlでは0が偽とみなされるという事実を利用しています。結果として、最初の比較が等しい場合(つまり0と評価された場合)、2番目の比較に「フォールスルー」し、0以外の値が見つかるか、最後まで続きます。
Python、Ruby、Haskellなどの一部の言語では、リストの比較は辞書式に行われます。つまり、値を必要な順序でリストに入れることで、上記の例のような比較のチェーンを構築できます。たとえば、 Ruby では次のようになります。
[ a .ユニット, a .ランク, a .名前] <=> [ b .ユニット, b .ランク, b .名前]C++の場合:
std :: tie ( a.unit , a.rank , a.name ) < = > std :: tie ( b.unit , b.rank , b.name )SQL結合演算子
一部のSQL方言では、はnullセーフな<=>結合演算子として使用され、両方のオペランドがnullの場合に一致します。[ 7 ]
参照
注記
- ^例えば、 IBM 7094のアキュムレータとストレージ(CAS)を比較し、論理アキュムレータとストレージ(LAS)を比較します。 [ 1 ]
参考文献
- ^ 「制御命令」(PDF) . IBM 7094動作原理(PDF) . システム・リファレンス・ライブラリー. 53ページ . A22-6703-4 . 2025年9月22日閲覧
- ^ Data.Ord
- ^ 「Math::Complex」 . Perlプログラミングドキュメント. 2014年9月26日閲覧
- ^ハーブ・サッターは、 「一貫性のある比較」と題された論文の中で、 C++標準に3者間比較演算子を追加することを提案しました。 「一貫性のある比較」
<=>を参照。この提案は2017年11月にC++20ドラフトに統合されました。 - ^ 「宇宙船の歴史(Re: [dart-misc] DEP 会議メモ)」。
- ^ 「スーパー・スペースシップ・オペレーター」 2000年12月8日. 2014年8月6日閲覧。
- ^ https://dev.mysql.com/doc/refman/8.4/en/comparison-operators.html#operator_equal-to